package crayon.reportapphis;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.xmlpull.v1.XmlSerializer;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;
import crayon.reportapphis.util.GDB;

public class AppService extends Service {
	
	private Timer timer;
	private TimerTask task = new TimerTask() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			GDB.log(getClass(),">>   call >>>>");
			collectRunnableTaskInfo();
			collectionApplication();
		}
	};

	@Override
	public IBinder onBind(Intent arg0) {
		GDB.log(getClass(),">>OnBind>>>>>>>>");
		// TODO Auto-generated method stub
		return null;
	}
	/** Called when the activity is first created. */

	@Override
	public void onCreate() {
		GDB.log(getClass(),">>onCreate>>>>>>>>");
		// TODO Auto-generated method stub
		Toast.makeText(this, "Background service started", Toast.LENGTH_SHORT).show();
		super.onCreate();
		timer = new Timer(getClass().getCanonicalName());
		timer.schedule(task, 100L, 60*1000L);
	}

	@Override
	public void onDestroy() {
		GDB.log(getClass(),">>onDestroy>>>>>>>>");
		// TODO Auto-generated method stub
		super.onDestroy();
		if(timer!=null){ 
			timer.cancel();timer=null;
		}
	}

	@Override
	public void onStart(Intent intent, int startId) {
		GDB.log(getClass(),">>onStart>>>>>>>>");
		// TODO Auto-generated method stub
		Toast.makeText(this, "###Background service started", Toast.LENGTH_SHORT).show();
		super.onStart(intent, startId);
	}


	private void collectRunnableTaskInfo(){
		GDB.log(getClass(),">>InitializeSituations()>>>>>>>>");
		ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);  
		List<RunningTaskInfo> infos = am.getRunningTasks(10); 
		GDB.log(getClass(),">>> size = " +  infos.size());
		for( RunningTaskInfo info : infos){
			GDB.log(getClass(),"\t\t>>> = " +  info.topActivity.getClassName());
			GDB.log(getClass(),"\t\t>>> = " +  info.topActivity.getPackageName());
		}
	}

	private static final String DATE_FORMAT="Date: %s";
	private void collectionApplication(){
		GDB.log(getClass(),"\t\t>START COLLECTION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = " );
		PackageManager manager =getPackageManager();
		List<PackageInfo>infos  =manager.getInstalledPackages(10);
		if(infos==null)return;

		hashtable.clear();
		boolean bHuck=false;
		Runtime runtime = Runtime.getRuntime();
		try {
			//			Process process = runtime.exec("/system/bin/ps");
			//			Process process = runtime.exec("dumpsys meminfo");
			Process process = runtime.exec("dumpsys");
			InputStream out = process.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(out));
			String line;
			String today=getToday();
			String yesterday = getYesterDay();
			while ((line = reader.readLine()) != null) {
				if(line.contains(today))   bHuck=false;
				if(line.contains(yesterday))bHuck=true;//
				if(bHuck){
					for(PackageInfo info :infos){
						if(line.contains(info.packageName) && line.contains("times") && line.contains("ms")){
							GDB.log(getClass(),"Package" + line);
							if( !hashtable.containsKey(info.packageName)){
								hashtable.put(info.packageName, new Item(info.packageName,line));
							}
						}
					}
				}
			}
			process.getErrorStream().close();
			process.getOutputStream().close();
			process.getInputStream().close();
			process.waitFor();

		} catch (Throwable e) {
			e.printStackTrace();
		} finally{
			GDB.log(getClass(),"\t\t>END COLLECTION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = " );
			pushToService();
		}

	}

	private void pushToService(){
		if(hashtable==null)return;

		
	

		TelephonyManager systemService = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
		Iterator it = hashtable.keySet().iterator();
		XmlSerializer serializer  = Xml.newSerializer();
		StringWriter writer = new StringWriter();
		try {
			serializer.setOutput(writer);
			serializer.startDocument("UTF-8", true);
			serializer.startTag("", "command");

			serializer.startTag("", "info");

			serializer.startTag("", "current");
			serializer.text(new SimpleDateFormat ( "yyyy.MM.dd HH:mm:ss", Locale.KOREA ).format(new Date()));
			serializer.endTag("", "current");

			serializer.startTag("", "logdate");
			serializer.text(getYesterDay());
			serializer.endTag("", "logdate");

			serializer.startTag("", "phonenumber");
			serializer.text(systemService.getLine1Number());
			serializer.endTag("", "phonenumber");

			serializer.startTag("", "deviceid");
			serializer.text(systemService.getDeviceId());
			serializer.endTag("", "deviceid");


			serializer.startTag("", "operator");
			serializer.text(systemService.getNetworkOperator());
			serializer.endTag("", "operator");

			serializer.endTag("", "info");
			serializer.startTag("", "messages");
			while (it.hasNext()) {
				Item item = hashtable.get((String)it.next());
				serializer.startTag("", "item");
				serializer.startTag("", "packagename");
				serializer.text(item.getPackageName());
				serializer.endTag("", "packagename");
				serializer.startTag("", "times");
				serializer.text(item.getTimes());
				serializer.endTag("", "times");
				serializer.startTag("", "ms");
				serializer.text(item.getMs());
				serializer.endTag("", "ms");
				serializer.endTag("", "item");
			}

			serializer.endTag("", "messages");
			serializer.endTag("", "command");

			serializer.endDocument();

//			uploadHttp(writer.toString());
		} catch (Exception e) {
			// TODO: handle exception
		} finally{


		}
		writer.toString();
		GDB.log(getClass(),writer.toString());
		//		return writer.toString();
	}
	Handler responseHandler = new Handler(){

	};
	private void uploadHttp(final String data) throws Exception{

		//		(Activity)this.Activity:runOnUiThread
		new Handler().post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				String url = "http://192.168.10.2:8080/login.jsp";
				HttpClient http = new DefaultHttpClient();
				try { 
					// 서버에 전달할 파라메터 세팅   
					ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
					nameValuePairs.add(new BasicNameValuePair("command", data));

					//     응답시간이 5초가 넘으면 timeout 처리하려면 아래 코드의 커맨트를 풀고 실행한다.
					HttpParams params = http.getParams();
					HttpConnectionParams.setConnectionTimeout(params, 5000);
					HttpConnectionParams.setSoTimeout(params, 5000);

					// HTTP를 통해 서버에 요청을 전달한다.
					// 요청에 대한결과는 responseHandler의 handleResponse()메서드가 호출되어 처리한다.
					// 서버에 전달되는 파라메터값을 인코딩하기위해 UrlEncodedFormEntity() 메서드를 사용한다.
					HttpPost httpPost = new HttpPost(url);
					UrlEncodedFormEntity entityRequest = new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
					httpPost.setEntity(entityRequest);
					http.execute(httpPost); 
				}catch(Exception e){e.printStackTrace();}
			}
		});

	}
	private String getToday(){
		Date now = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		String today = String.format(DATE_FORMAT, format.format(new Date()));
		//	      GDB.log(getClass(),"Today:" + today);

		return today;
	}

	private String getYesterDay(){
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1);

		String y_year = Integer.toString(cal.get(Calendar.YEAR));
		String y_month = Integer.toString(cal.get(Calendar.MONTH)+1);
		String y_date = Integer.toString(cal.get(Calendar.DATE));

		if(y_month.length() ==1 ) y_month = "0" +y_month; //month 3 => 03
		if(y_date.length() ==1 ) y_date = "0" +y_date;  //day 7=> 07
		String yesterday = String.format(DATE_FORMAT, (y_year + y_month + y_date));
		//      GDB.log(getClass(),"Yesterday:" +yesterday);
		return yesterday;
	}

	Hashtable<String, Item> hashtable = new Hashtable<String, AppService.Item>();

	class Item{
		Item(String pkname,String data){
			if(data==null)return;
			setPackageName(pkname);
			String[] div = data.split(":");//페키지명부분을 삭제한다.
			String line = div[1];
			line=line.trim();
			String[] split = line.split(",");//횟수와 실행시간을 분리한다.
			if(split.length ==2){
				String time = split[0].replace("times", "");
				if(time!=null ){
					time =  time.trim();
					setTimes(time);
					GDB.log(getClass(),"time=" +time);
				}
				String nms = split[1].replace("ms", "");
				if(nms!=null ){
					nms=  nms.trim();
					setMs(nms);
					GDB.log(getClass(),"nms=" +nms);
				}
			}
		}
		String packageName,times,ms;
		public String getPackageName() {
			return packageName;
		}
		public void setPackageName(String packageName) {
			this.packageName = packageName;
		}
		public String getTimes() {
			return times;
		}
		public void setTimes(String times) {
			this.times = times;
		}
		public String getMs() {
			return ms;
		}
		public void setMs(String ms) {
			this.ms = ms;
		}
	}


}